﻿using Microsoft.EntityFrameworkCore;

namespace Devonline.AspNetCore;

/// <summary>
/// 附件及文件操作类服务
/// </summary>
/// <typeparam name="TDbContext">数据库上下文</typeparam>
/// <typeparam name="TEntitySet">业务数据类型</typeparam>
/// <typeparam name="TAttachment">附件数据类型</typeparam>
/// <typeparam name="TKey">主键类型</typeparam>
public interface IDataWithAttachmentService<TDbContext, TEntitySet, TAttachment, TKey> :
    IAttachmentService<TDbContext, TAttachment, TKey>,
    IDataService<TDbContext, TEntitySet, TKey>
    where TDbContext : DbContext
    where TEntitySet : class, IEntitySet<TKey>
    where TAttachment : class, IAttachment<TKey>
    where TKey : IConvertible
{
    /// <summary>
    /// 新增附件
    /// </summary>
    /// <param name="entitySet">业务数据</param>
    /// <param name="attachments">附件集合</param>
    /// <param name="businessType">业务类型</param>
    /// <returns>待删除文件列表, 请在数据库事物提交成功后删除列表中的文件</returns>
    Task AddAttachmentsAsync(TEntitySet entitySet, IEnumerable<TAttachment>? attachments = default, string? businessType = default);
    /// <summary>
    /// 修改附件, 保留旧附件, 新增新附件, 返回待删除文件列表
    /// </summary>
    /// <param name="entitySet">业务数据</param>
    /// <param name="attachments">附件集合</param>
    /// <param name="businessType">业务类型</param>
    /// <param name="isLogical">是否逻辑操作, 默认不是</param>
    /// <returns>待删除文件列表, 请在数据库事物提交成功后删除列表中的文件</returns>
    Task<IEnumerable<string>> UpdateAttachmentsAsync(TEntitySet entitySet, IEnumerable<TAttachment>? attachments = default, string? businessType = default, bool isLogical = false);
    /// <summary>
    /// 自动删除附件, 返回待删除文件列表, 适用于实体对象模型从数据库删除时查找原始附件并自动删除
    /// </summary>
    /// <param name="id">业务数据主键</param>
    /// <param name="businessType">业务类型</param>
    /// <param name="isLogical">是否逻辑操作, 默认不是</param>
    /// <returns>待删除文件列表, 请在数据库事物提交成功后删除列表中的文件</returns>
    Task<IEnumerable<string>?> DeleteAttachmentsAsync(TKey id, string? businessType = default, bool isLogical = false);
    /// <summary>
    /// 按文件列表删除附件
    /// </summary>
    /// <param name="fileNames">待删除的文件名</param>
    /// <param name="isLogical">是否逻辑操作, 默认不是</param>
    /// <returns></returns>
    Task<IEnumerable<string>?> DeleteAttachmentsAsync(IEnumerable<string> fileNames, bool isLogical = false);

    /// <summary>
    /// 新增附件
    /// </summary>
    /// <typeparam name="TModel">业务数据类型</typeparam>
    /// <param name="model">业务数据</param>
    /// <param name="attachments">附件集合</param>
    /// <param name="businessType">业务类型</param>
    /// <returns>待删除文件列表, 请在数据库事物提交成功后删除列表中的文件</returns>
    Task AddAttachmentsAsync<TModel>(TModel model, IEnumerable<TAttachment>? attachments = default, string? businessType = default) where TModel : class, IEntitySet<TKey>;
    /// <summary>
    /// 修改附件, 保留旧附件, 新增新附件, 返回待删除文件列表
    /// </summary>
    /// <typeparam name="TModel">业务数据类型</typeparam>
    /// <param name="model">业务数据</param>
    /// <param name="attachments">附件集合</param>
    /// <param name="businessType">业务类型</param>
    /// <param name="isLogical">是否逻辑操作, 默认不是</param>
    /// <returns>待删除文件列表, 请在数据库事物提交成功后删除列表中的文件</returns>
    Task<IEnumerable<string>> UpdateAttachmentsAsync<TModel>(TModel model, IEnumerable<TAttachment>? attachments = default, string? businessType = default, bool isLogical = false) where TModel : class, IEntitySet<TKey>;
}

/// <summary>
/// 附件及文件操作类服务
/// 字符串作为主键的默认实现
/// </summary>
/// <typeparam name="TDbContext">数据库上下文</typeparam>
/// <typeparam name="TEntitySet">业务数据类型</typeparam>
public interface IDataWithAttachmentService<TDbContext, TEntitySet> :
    IDataWithAttachmentService<TDbContext, TEntitySet, Attachment, string>,
    IAttachmentService<TDbContext>,
    IDataService<TDbContext, TEntitySet>
    where TDbContext : DbContext
    where TEntitySet : class, IEntitySet<string>
{ }